home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d13 / rmt10.arc / RMT10.C < prev    next >
Text File  |  1990-07-20  |  10KB  |  306 lines

  1. /********************************************************************
  2.                        Richard's Menu Tools
  3.  
  4. July 1990                                                Revision 1.0
  5.  
  6. Released as public domain
  7. ********************************************************************/
  8.  
  9. #define TRUE 1
  10. #define FALSE 0
  11.  
  12. #include "alloc.h"
  13. #include "conio.h"
  14. #include "rmt10.h"
  15.  
  16. /********************************************************************
  17. Name  : menu_show_item
  18. Input : menu-pointer
  19.         entry number to show
  20.         selected-state flag
  21. Output: none
  22. Descr.: displays the entry which corresponds to the entry-number
  23.         in normal,selected or disabled color (depends on
  24.         selected-state flag and entry status) and highlights
  25.         the hot-key-char. if entry is enabled.
  26. ********************************************************************/
  27. void menu_show_item(void *mnu_ptr, unsigned ent_nr, int selflg)
  28. {
  29.   char *bstr;
  30.   struct mnu_entry *ment;
  31.   struct mnu_hdr *mhdr;
  32.   char blstr[82];
  33.  
  34.   bstr = "                                                                                  ";
  35.  
  36.   /* init pointer */
  37.   mhdr = mnu_ptr;
  38.   ment = mnu_ptr;
  39.   ment += ent_nr * mnu_esize + mnu_hsize;
  40.   strncpy(blstr,bstr,mhdr->maxmsg+2);
  41.   blstr[mhdr->maxmsg+2] = 0;
  42.   if (ment->status & mnu_selectable)
  43.     if (selflg) {
  44.       textattr(mhdr->mcolor);
  45.       gotoxy(39-div(mhdr->maxmsg,2),mhdr->msgln);
  46.       cprintf("%s",blstr);
  47.       gotoxy(40-div(strlen(ment->msg),2),mhdr->msgln);
  48.       printf("%s",ment->msg);
  49.       textattr(mhdr->scolor);
  50.     }
  51.     else
  52.       textattr(mhdr->ncolor);
  53.   else
  54.     textattr(mhdr->dcolor);
  55.   gotoxy(ment->x,ment->y);
  56.   cprintf("%s",ment->txt);
  57. /*  if (!selflg && ment->status & mnu_selectable) { */
  58.     if ((ment->status & mnu_selectable) == 1) {
  59.       if (!selflg)
  60.         textattr(mhdr->hcolor);
  61.       else
  62.         textattr((mhdr->scolor & 0xf0) | (mhdr->hcolor & 0x0f));
  63.     gotoxy(ment->x + ment->HKpos,ment->y);
  64.     cprintf("%c",ment->txt[ment->HKpos]);
  65.   }
  66. }
  67.  
  68. /********************************************************************
  69. Name  : menu-proc
  70. Input : menu-pointer
  71. Output: number of selected entry (-1 if 'ESC' is pressed)
  72. Descr.: processes the menu in a way that it takes care of highliting
  73.         the current entry, checking all the pressed keys, calling
  74.         an entry-function(if enabled) and returns the number of the
  75.         selected entry.
  76. ********************************************************************/
  77. char menu_proc(void *mnu_ptr)
  78. {
  79.   struct mnu_hdr *mhdr;
  80.   struct mnu_entry *ment;
  81.   int pos_cnt,old_pos,cur_pos;
  82.   unsigned *ent_cnt;
  83.   int key;
  84.   int spkey;
  85.   int retval;
  86.   int act_entry,mnu_ex;
  87.   int i;
  88.  
  89.   /* init pointer */
  90.   mhdr = mnu_ptr;
  91.  
  92.   ment = mnu_ptr;
  93.   ment += mnu_hsize;
  94.   pos_cnt = 0;
  95.   while (((ment->status & mnu_selectable) == 0) && (pos_cnt < mhdr->cnt-1)) {
  96.     ment = mnu_ptr;
  97.     ment += ++pos_cnt * mnu_esize + mnu_hsize;
  98.   }
  99.   menu_show_item(mnu_ptr, pos_cnt,TRUE);
  100.   do {
  101.     do {
  102.       key = getch();
  103.       if (key == 0) {  /* scan-code following for special-key */
  104.         spkey = TRUE;
  105.         key = getch();
  106.       }
  107.       else {
  108.         spkey = FALSE;
  109.         if (key >= 'a' && key <= 'z')
  110.           key -= 32;
  111.       }
  112.       menu_show_item(mnu_ptr, pos_cnt,FALSE);
  113.       old_pos = pos_cnt;
  114.       act_entry = mnu_ex = FALSE;
  115.       do {
  116.         switch (spkey) {
  117.           case TRUE:
  118.             switch (key) {
  119.               case 75: if ((mhdr->status & mnu_horact) != 0) {
  120.                          pos_cnt--;
  121.                          if (pos_cnt < 0)
  122.                            pos_cnt = mhdr->cnt - 1;
  123.                        }
  124.                        else
  125.                          if ((mhdr->status & mnu_horsel) != 0) {
  126.                            act_entry = TRUE;
  127.                          }
  128.                        break;
  129.               case 72: if ((mhdr->status & mnu_veract) != 0) {
  130.                          pos_cnt--;
  131.                          if (pos_cnt < 0)
  132.                            pos_cnt = mhdr->cnt - 1;
  133.                        }
  134.                        else
  135.                          if ((mhdr->status & mnu_versel) != 0) {
  136.                            act_entry = TRUE;
  137.                          }
  138.                        break;
  139.               case 77: if ((mhdr->status & mnu_horact) != 0) {
  140.                          pos_cnt++;
  141.                          if (pos_cnt == mhdr->cnt)
  142.                            pos_cnt = 0;
  143.                        }
  144.                        else
  145.                          if ((mhdr->status & mnu_horsel) != 0) {
  146.                            act_entry = TRUE;
  147.                          }
  148.                        break;
  149.               case 80: if ((mhdr->status & mnu_veract) != 0) {
  150.                          pos_cnt++;
  151.                          if (pos_cnt == mhdr->cnt)
  152.                            pos_cnt = 0;
  153.                        }
  154.                        else
  155.                          if ((mhdr->status & mnu_versel) != 0) {
  156.                            act_entry = TRUE;
  157.                          }
  158.                        break;
  159.             }
  160.             break;
  161.           case FALSE:
  162.             switch (key) {
  163.               case 13:
  164.                 act_entry = TRUE;
  165.                 break;
  166.               case 27:
  167.                 mnu_ex = TRUE;
  168.                 break;
  169.               default:
  170.                 for (i = 0; i < mhdr->cnt; i++) {
  171.                   cur_pos = (old_pos + i + 1) % mhdr->cnt;
  172.                   ment = mnu_ptr;
  173.                   ment += cur_pos * mnu_esize + mnu_hsize;
  174.                   if (ment->status & mnu_selectable && ment->HKey == key) {
  175.                     pos_cnt = cur_pos;
  176.                     act_entry = mhdr->status & mnu_autoselect;
  177.                     break;
  178.                   }
  179.                 }
  180.                 break;
  181.               }
  182.         }
  183.         ment = mnu_ptr;
  184.         ment += pos_cnt * mnu_esize + mnu_hsize;
  185.       } while (!(ment->status & mnu_selectable) && old_pos != pos_cnt);
  186.       menu_show_item(mnu_ptr, pos_cnt,TRUE);
  187.     } while (!act_entry && !mnu_ex);
  188.     if (ment->func != NULL && !mnu_ex) {
  189.       (*ment->func)();
  190.       menu_show_item(mnu_ptr, pos_cnt,FALSE);
  191.       menu_show_item(mnu_ptr, pos_cnt,TRUE);
  192.     }
  193.     else
  194.       mnu_ex = TRUE;
  195.   } while (!mnu_ex);
  196.   if (act_entry)
  197.     retval = pos_cnt;
  198.   else
  199.     retval = -1;
  200.   return(retval);
  201. }
  202.  
  203. /********************************************************************
  204. Name  : menu_add
  205. Input : menu-pointer
  206.         x-position of the entry
  207.         y-position of the entry
  208.         entry-text
  209.         corresponding message line
  210.         hot-key-char. position (entry-textv relative)
  211.         hot-key-char.
  212.         status: bit 0: mnu_selectable - entry selectable
  213.         entry-function
  214. Output: none
  215. Descr.: stores the information for the entry and shows it
  216.         in normal state
  217.         The different hot-key-char. position and hot-key-char.
  218.         enables you to highlight one char. in the entry-text and
  219.         make the menu respond to an other key (i.e. if you have
  220.         a special char.-set)
  221.         the entry-function will be called if the entry is selected,
  222.         and the pointer is not NULL
  223. ********************************************************************/
  224. void menu_add(void *mnu_ptr, int x, int y, char *ent_txt, char *ent_msg, int hkpos, char hk, int stat, void (*func)())
  225. {
  226.   struct mnu_hdr *mhdr;
  227.   struct mnu_entry *ment;
  228.  
  229.   /* init pointer */
  230.   mhdr = mnu_ptr;
  231.   ment = mnu_ptr;
  232.   ment += mhdr->cnt * mnu_esize + mnu_hsize;
  233.  
  234.   /* save menu-entry data */
  235.   ment->x = x;
  236.   ment->y = y;
  237.   ment->txt = ent_txt;
  238.   ment->msg = ent_msg;
  239.   ment->HKpos = hkpos;
  240.   ment->HKey = hk;
  241.   ment->func = func;
  242.   ment->status = stat;
  243.   if (strlen(ent_msg) > mhdr->maxmsg)
  244.     mhdr->maxmsg = strlen(ent_msg);
  245.   (mhdr->cnt)++;
  246.  
  247.   /* show menu-entry text */
  248.   menu_show_item(mnu_ptr, mhdr->cnt - 1, FALSE);
  249. }
  250.  
  251. /********************************************************************
  252. Name  : menu_init
  253. Input : number of menu enries
  254.         color for normal entry (textattr-form: backgnd*16+foregnd)
  255.         color for selected entry
  256.         color for deactivated entry
  257.         color for hot-key-char.
  258.         color for message-line
  259.         status: bit 0: mnu_autoselect - entries are selected by pressing the hotkey
  260.                     1: mnu_horact - horizontal cursor-keys are active for moving
  261.                     2: mnu_veract - vertical cursor-keys are active for moving
  262.                     3: mnu_horsel - horizontal cursor-keys select entry
  263.                     4: mnu_versel - vertical cursor-keys select entry
  264.         y-position for message-line
  265. Output: pointer to allocated memory
  266. Descr.: Allocates the needed memory for the menu, saves the header data
  267.         and returns the pointer to the allocated memory.
  268. ********************************************************************/
  269. void *menu_init(size_t nr_ent, int nclr, int sclr, int dclr, int hclr, int mclr, int stat, int msgln)
  270. /* in: max_ent... number of menu entries
  271.    out: pointer to reserved memory
  272. */
  273. {
  274.   void *mnu_ptr;
  275.   struct mnu_hdr *mhdr;
  276.  
  277.   unsigned ccc;
  278.   mhdr = mnu_ptr = malloc(nr_ent*sizeof(struct mnu_entry) + sizeof(struct mnu_hdr));
  279.   if (mnu_ptr != NULL) {
  280.     mhdr->cnt = 0;         /* entry counter */
  281.     mhdr->ncolor = nclr;   /* normal entry color */
  282.     mhdr->scolor = sclr;   /* selected entry color */
  283.     mhdr->dcolor = dclr;   /* deactivated entry color */
  284.     mhdr->hcolor = hclr;   /* hot-key-char. color */
  285.     mhdr->mcolor = mclr;   /* message-line color */
  286.     mhdr->msgln  = msgln;  /* y-position of the message line */
  287.     mhdr->maxmsg = 0;      /* length of the longest message line */
  288.     mhdr->status = stat;   /* menu status */
  289.   }
  290.   return(mnu_ptr);
  291. }
  292.  
  293. /********************************************************************
  294. Name  : menu_exit
  295. Input : menu-pointer
  296. Output: none
  297.  
  298. Descr.: Takes the pointer to the allocated memory for the menu
  299.         and frees it.
  300. ********************************************************************/
  301. void menu_exit(void *mnu_ptr)
  302. {
  303.   free(mnu_ptr);
  304. }
  305.  
  306.